package Study;

import Format.Parent;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import lombok.Data;
import org.apache.commons.codec.digest.HmacAlgorithms;
import org.apache.commons.codec.digest.HmacUtils;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
import org.springframework.util.StringUtils;
import util.MD5Utils;

import java.io.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

public class knowledge {
    public knowledge() {
    }

    @Data
    class Person {
        protected String name;
        protected String age;

        public Person(String name) {
            this.name = name;
        }

        public Person(String name, String age) {
            this(name);
            this.age = age;
        }
    }

    class Student extends Person {
        private String name;

        public Student(String name, String name1) {
            super(name);
            this.name = name1;
        }

        public void getInfo() {
            System.out.println(this.name);//Child
            System.out.println(super.name);//Father
        }
    }

    @Test
    public void test1() {
        Student student = new Student("父亲", "儿子");
        student.getInfo();
    }

    @Test
    public void test2() {
        //跳出多重循环  可以在最外层循环语句定义一个标号，然后再里层循环体的代码中使用带有标号的break语句，即可跳出外层循环
        ok:
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < 4; j++) {
                if (j == 2) {
                    break ok;
                }
                System.out.println("i=" + i + ",j=" + j);
            }
        }
        //跳出当前循环体
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < 4; j++) {
                if (j == 2) {
                    break;
                }
                System.out.println("i=" + i + ",j=" + j);
            }
        }
        //结束本次循环
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < 4; j++) {
                if (j == 2) {
                    continue;
                }
                System.out.println("i=" + i + ",j=" + j);
            }
        }
    }

    private String sex = "男";
    private static Integer a = 2;

    static class staClass {
        public void visit() {
            System.out.println("我只能访问静态成员变量:" + a);
        }
    }

    @Test
    public void test3() {
        staClass staClass = new staClass();
        staClass.visit();
        knowledge knowledge = new knowledge();
        memberClass memberClass = knowledge.new memberClass();
        memberClass.visit();
    }

    class memberClass {
        public void visit() {
            System.out.println("我啥都可以访问" + a + sex);
        }
    }

    @Test
    public void test4() {
        String aa = new String("ab");//a 为1个引用
        String bb = new String("ab");//b 为另一个引用，对象的内容一样
        String a = "ab"; //放在常量池中
        String b = "ab";//从常量池中查找
        if (aa == bb) // true
            System.out.println("aa==bb");
        if (a == b) // false，非同一对象
            System.out.println("a==b");
        if (a.equals(b)) // true
            System.out.println("aEQb");
        if (42 == 42.0) { // true
            System.out.println("true");
        }
    }


    @Test
    public void test5() {
        Integer num1, num2;
        num1 = 10;
        num2 = 20;
        swap(num1, num2);
        System.out.println("num1 = " + num1);
        System.out.println("num2 = " + num2);
    }

    public void swap(Integer a, Integer b) {
        Integer temp = a;
        a = b;
        b = temp;
        System.out.println("a = " + a);
        System.out.println("b = " + b);
    }

    @Test
    public void test6() {
        Person p = new Person("张三");
        swap(p);
        System.out.println(p.getName());
    }

    public void swap(Person person) {
        person.setName("李四");
        System.out.println(person);
    }

    @Test
    public void test7() throws Exception {
        List<String> list = IOUtils.readLines(new FileReader(new File("")));
    }

    @Test
    public void test8() {
        String a = "马佳帅(控)";
        String b = "付正傲";
        String replace = null;
        try {
            replace = a.replace("(控)", "");
        } catch (Exception e) {
            e.printStackTrace();
        }
        String replace1 = b.replace("(控)", "");
        System.out.println(replace);
        System.out.println(replace1);
    }

    @Test
    public void test9() {
        String a = "abcdefg";
        System.out.println(a);
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(a);
        stringBuilder.reverse();
        System.out.println(stringBuilder);

    }


    @Test
    public void test11() {
        String a = "张三三";
        String replace = a.replace("三", "四");
        System.out.println(replace);
    }

    @Test
    public void test12() {
        String a = null;
        if (!"ha".equals(a)) {
            System.out.println("哈哈");
        }
    }

    @Test
    public void test13() {
//        String newSpecialPaper = "";
//        System =out.println(StringUtils.isEmpty(newSpecialPaper));
        String a = "abc,cbd,weq,eww,qwe,ewq,eoi,opo";
        String[] split = a.split(",");
        String b = "ww";
        for (int i = 0; i < split.length; i++) {
            if (split[i].contains(b)) System.out.println(i + 1);
        }


    }

    @Test
    public void test14() {
        Long a = 123123098123018212L;

        Long b = 13192731092371092L;
        double v = a.doubleValue() / b.doubleValue();
        System.out.println(v);
    }

    @Test
    public void test15() {
        List<Map> maps = JSONObject.parseArray(null, Map.class);
        System.out.println(maps);
    }

    @Test
    public void test16() {
        ArrayList<Object> list = Lists.newArrayList();
        list.add("x");
        List<Object> objects = Collections.unmodifiableList(list);
        objects.add("y");
        System.out.println(list.size());
    }

    @Test
    public void test17() {
        ArrayList<Object> list = Lists.newArrayList();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);

        for (Object o : list) {
            System.out.println(o);
//            list.remove(o);//不可以删除
        }
        ListIterator<Object> objectListIterator = list.listIterator();
        while (objectListIterator.hasNext()) System.out.println(objectListIterator.next());
        while (objectListIterator.hasPrevious()) System.out.println(objectListIterator.previous());
    }

    @Test
    public void test18() {
        HashSet<Object> set = Sets.newHashSet();
        set.add(1);
        set.add(2);
        set.add(3);
        set.add(4);
        set.add(5);
        Iterator<Object> iterator = set.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }

    @Test
    public void test19() {
        ArrayList<Object> list = Lists.newArrayList();
//        list.add("张三");
//        list.add("李四");
//        list.add("王五");
        System.out.println(list);
        String string = JSON.toJSONString(list);
        System.out.println(string);
    }

    @Test
    public void test20() {
        int a = 9999;
        Integer c = 9999;
        System.out.println(c.equals(a));
        System.out.println(a == c);
        Long b = 9999L;
        Long d = 9999L;
        System.out.println(b.equals(d));
        System.out.println(b == d);
        System.out.println(b.equals(a));
        System.out.println(a == b.intValue());

    }

    @Test
    public void test21() {
        Queue<String> queue = new LinkedList<>();
        System.out.println(queue.add("张三"));
        System.out.println(queue.offer("李四"));
        System.out.println(queue);
        System.out.println(queue.poll());
        System.out.println(queue.remove());
        System.out.println(queue.poll());//返回null
        System.out.println(queue.remove());//直接报错
    }

    @Test
    public void test22() {
        Parent parent = new Parent();
        parent.setAddress("地球");
        parent.setAge("24");
        parent.setName("张三");
        parent.setSalary(new BigDecimal(2));
        String firstParent = JSON.toJSONString(parent);
        Parent parent2 = new Parent();
        parent2.setAddress("地球");
        parent2.setAge("24");
        parent2.setName("张三");
        parent2.setSalary(new BigDecimal(2));
        String secondParent = JSON.toJSONString(parent2);
        String s = MD5Utils.md5(firstParent);
        String s1 = MD5Utils.md5(secondParent);
        System.out.println(s.equals(s1));
        System.out.println(firstParent.equals(secondParent));
    }

    @Test
    public void test23() {
        ConcurrentHashMap concurrentHashMap = new ConcurrentHashMap();
        concurrentHashMap.put("a", 1);
    }

    @Test
    public void test24() {
//        Double a = 10.0;
//        Double b = 2.9;
//        double v = a / b;
//        double v1 = BigDecimal.valueOf(v*10).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
//        System.out.println(v1);
        String s = "2022-03-01 00:00:00";
        String b = "";
        String c = " ";
        String substring = s.substring(0, 10);
        System.out.println(substring);
        System.out.println(StringUtils.hasText(b));
        System.out.println(StringUtils.hasLength(b));

        System.out.println(StringUtils.hasText(c));
        System.out.println(StringUtils.hasLength(c));
    }

    @Test
    public void test25() {
//        String s = "你在想什么";
//        System.out.println(StrUtil.hasBlank(s));
//        System.out.println(StrUtil.isBlank(s));
//        System.out.println(StrUtil.BRACKET_END);
        HmacUtils hmacUtils = new HmacUtils(HmacAlgorithms.HMAC_SHA_1, "secret-1234567890abc");
        System.out.println(hmacUtils.hmacHex("1234567890abc" + "1496631984"));
    }

    @Test
    public void test26() {
        Conversion.Parent parent = new Conversion.Parent();
        System.out.println(parent);
    }

    @Test
    public void test27() {
        ArrayList<Object> list = Lists.newArrayList();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        list.add(6);
        list.add(7);
        list.add(8);
        list.add(9);
        list.add(10);
        System.out.println(list.containsAll(Arrays.asList(1, 2, 3, 4, 7, 8, 10)));
    }

    @Test
    public void test28() {
        Integer a = 5;
        Optional.ofNullable(a).ifPresent(o -> o = o + 5);
        List<Integer> vehicleList = Arrays.asList(3, 5, 7, 9);
    }

    @Test
    public void test29() {
//        List<Integer> vehicleList = Arrays.asList(3, 5, 7, 9);
//
//        if(vehicleList.contains(3)){
//            System.out.println("哈哈");
//        }else{
//
//        }
        String p = "18231157516*";
        String q = "18231157516";
        System.out.println(p.replace("*", ""));
        System.out.println(q.replace("*", ""));
    }

    @Test
    public void test30() {
        Parent parent = new Parent();
        parent.setName("张三");
        parent.setAge("15");
        Parent parent1 = new Parent();
        parent1.setName(parent.getName());
        parent.setName("李四");
        System.out.println(JSONObject.toJSONString(parent));
        System.out.println(JSONObject.toJSONString(parent1));
    }

    @Test
    public void test31() {
        Lock lock = new ReentrantLock();
        lock.lock();
        try {
            System.out.println("获得锁");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("释放锁");
            lock.unlock();
        }
    }

    @Test
    public void test32() {
        long round = Math.round(-11.5);  //-11
        long round1 = Math.round(-11.4);//-11
        long round2 = Math.round(-11.6);//-12
        System.out.println(round);
        System.out.println(round1);
        System.out.println(round2);
    }

    @Test
    public void test33() {
        String a = "i";
        String b = "i";
        System.out.println(a == b);
        System.out.println(a.equals(b));
        String c = new String("i");
        String d = new String("i");
        System.out.println(a.equals(c));
        System.out.println(a == c);
        System.out.println(c == d);
        System.out.println(c.equals(d));

    }

    @Test
    public void test34() {
        StringBuilder a = new StringBuilder("abcdef");
        System.out.println(a.reverse());
    }

    @Test
    public void test35() {
        String a = "你快乐了嘛";
        String b = "abcd";
        String c = "ABCD";
        String d = " ab ";
        System.out.println(a.length());
        System.out.println(a.charAt(2));
        System.out.println(a.indexOf("快"));
        System.out.println(a.substring(2));
        System.out.println(a.substring(1, 3));

        System.out.println(a.equals("你在想什么"));
        System.out.println(a.contains("快乐"));
        System.out.println(a.startsWith("你快"));
        System.out.println(a.endsWith("了嘛"));
        System.out.println(a.isEmpty());

        System.out.println(a.getBytes());
        System.out.println(a.toCharArray());
        System.out.println(String.valueOf(a.toCharArray()));
        System.out.println(b.toUpperCase());
        System.out.println(c.toLowerCase());
        System.out.println(b.concat(c));

        System.out.println(b.replace("a", "e"));
        System.out.println(d.trim());

    }

    @Test
    public void test36() {
        //hashMap的初始值为16 为2倍扩容
        HashMap<Object, Object> map = Maps.newHashMap();
        map.put(null, null);
        map.put("a", null);
        map.put("b", 123);
        System.out.println(map.size());
        for (Object o : map.keySet()) {
            System.out.println(map.get(o));
        }
        for (Map.Entry<Object, Object> objectObjectEntry : map.entrySet()) {
            System.out.println(objectObjectEntry.getKey() + " -- " + objectObjectEntry.getValue());
        }

    }

    @Test
    public void test37() {
        //hashMap的初始值为11 为2倍+1扩容
        Hashtable<Object, Object> table = new Hashtable<>();
        //会报错  因为hashtable 不允许k和v为null
        table.put(null, null);
        table.put("a", null);
        table.put("b", 123);
        System.out.println(table.size());
    }

    @Test
    public void test38() {
        Set<Object> set = Sets.newHashSet();
        ArrayList<Object> list = Lists.newArrayList();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(4);
        set.addAll(list);
        ArrayList<Object> list2 = Lists.newArrayList();
        list2.addAll(set);
        System.out.println(list2);
    }

    @Test
    public void test39() {
        List<Integer> list = Arrays.asList(33, 99, 3, 41);
        Optional<Integer> min = list.stream().min(Integer::compareTo);
        System.out.println(min.get());

    }

    class A {
        private String type;
        private String cry;

        public A(String type, String cry) {
            this.type = type;
            this.cry = cry;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }
    }

    public static void tranA(A a, A b) {
        System.out.println(a.getType() + b.getType());
        A c = a;
        System.out.println(c.getType());
        a = b;
        System.out.println(a.getType());
        b = c;
        System.out.println(b.getType());
        System.out.println(a.getType() + b.getType());
        System.out.println(a);
        System.out.println(c);
        System.out.println(b);

    }

    @Test
    public void tes() {
        A cat = new A("cat", "miaomiao");
        A dog = new A("dog", "wangwang");
        tranA(cat, dog);
        System.out.println(cat.getType() + dog.getType());
        System.out.println(cat);
    }

    @Test
    public void test40() {
        String userName = "马佳帅";
        String name = org.apache.commons.lang.StringUtils.left(userName, 1);
        System.out.println(userName.replaceFirst(name, "*"));

    }

    //每N个字符插入一个空格
    @Test
    public void test41() {
        String a = "1234621836212123123";
        String regex = "(.{4})";
        a = a.replaceAll(regex, "$1 ");
        System.out.println(a);

    }

    @Test
    public void test42() {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        list.stream().map(l -> {
            if (l < 3) return null;
            System.out.println(l);
            return l.doubleValue();
        }).collect(Collectors.toList());
    }

    @Test
    public void test43() {
        ArrayList<String> list = Lists.newArrayList("18231157516", "15652986977", "13671377626", "19838825322");
        if (list.contains("18231157516")) {
            System.out.println("hahahha");
        }
    }

    @Test
    public void test44() {
        String[] phone = {"1234567890"};
        String a = "";
        for (int i = 0; i < phone.length; i++) {
            a = phone[i];
        }
        System.out.println(a);
    }

    @Test
    public void test45() {
        Integer a = 0;
        Integer b = 0;
        while (a < 3) {
            b = ++a;
            System.out.println(b);
            System.out.println("这是第" + a + "次");
        }
    }

    @Test
    public void test46() {
        int[] nums1 = {1, 3};
        int[] nums2 = {2};
        System.out.println(findMedianSortedArrays(nums1, nums2));
    }

    @Test
    public void test47() {
        String s = "xaabacxcabaax";
//        xaabacxcabaax
        System.out.println(longestPalindrome(s));
    }

    public boolean isEqual(int i, int j, String s) {
        boolean a = false;
        char c = s.charAt(i++);
        char c1 = s.charAt(j--);
        a = c == c1;
        if (a && i < j) {
            a = isEqual(i, j, s);
        }
        return a;
    }

    public String longestPalindrome(String s) {
        if (s.length() == 0 || s.length() == 1) return s;
        int len = 1;
        String s1 = s.substring(0, 1);
        //暴力解法
        for (int i = 0; i < s.length() - 1; i++) {
            for (int j = i + 1; j < s.length(); j++) {
                if (isEqual(i, j, s) && len < j - i + 1) {
                    s1 = s.substring(i, j + 1);
                    len = s1.length();
                }
            }
        }
        return s1;
    }

    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
//        int[] num3 = ArrayUtils.addAll(nums1, nums2);
        int temp = 0;
        if (nums1 == null) {
            return 0.0;
        } else if (nums2 == null) {
            return 0.0;
        }
        int[] num3 = new int[nums1.length + nums2.length];
        System.arraycopy(nums1, 0, num3, 0, nums1.length);
        System.arraycopy(nums2, 0, num3, nums1.length, nums2.length);
//        Arrays.sort(num3);

        for (int i = 1; i < nums1.length + nums2.length; i++) {//第i次排序 只需要 length - 1 次
            for (int j = 0; j < nums1.length + nums2.length - i; j++) {
                if (num3[j] > num3[j + 1]) {
                    temp = num3[j];
                    num3[j] = num3[j + 1];
                    num3[j + 1] = temp;
                }
            }
        }
//        int[] num3 = new int[nums1.length + nums2.length];
//        for (int i = 0; i < nums1.length + nums2.length; i++) {
//
//        }
        int length = num3.length;
        if (length % 2 == 0) {
            int i = length / 2;
            int i1 = num3[i - 1] + num3[i];
            return (float) i1 / 2;

        } else {
            int i = length / 2;
            return num3[i];
        }
    }

    public int length(String s) {
        //l是字符串的长度 ans是最长字串的长度
        int l = s.length(), ans = 0;
        //创建一个map集合 key值为字符 value值为字符位置+1
        HashMap<Character, Integer> map = new HashMap<>();
        //存储起始点与结束点 结束的条件  ，end必定会自增
        for (int end = 0, start = 0; end < l; end++) {
            //获取最后一个元素
            char c = s.charAt(end);
            //判断map中是否已经含有该字符 如果存在移动开始位置
            if (map.containsKey(c)) {
                //比较最后值相同值在map的下标和起始位置，比较大的值赋给start，将它提升给value的下一个值
                //map.get(c)+1 是为了 找到重复的元素 从重复的元素开始  因为这个时候map中还未放入重复的key
                start = Math.max(map.get(c) + 1, start);
            }
            //比较最长的字符串和新串的长度，返回最长，因为start/end 为0 所以+1
            ans = Math.max(ans, end - start + 1);
            //将最后的值放入到map中
            map.put(s.charAt(end), end);
        }
        return ans;
    }

    public static long totalRows = 0;
    public static long blankRows = 0;
    public static long annotationRows = 0;

    public static void main(String[] args) throws FileNotFoundException, IOException {
        File file = new File("D:\\project\\Daqibao");
        count(file);
        System.out.println("总代代码行数:" + totalRows);
        System.out.println("空行代码行数:" + blankRows);
        System.out.println("注释代码行数:" + annotationRows);
        System.out.println("有效代码行数:" + (totalRows - blankRows));

    }

    public static void count(File file) throws FileNotFoundException, IOException {
        if (file.isDirectory()) {
            for (File t : file.listFiles()) {
                if (t.isDirectory()) {
                    count(t);
                } else if (t.isFile() && t.getName().endsWith(".java")) {
                    totalRows += rows(t);
                    blankRows += countBlanks(t);
                    annotationRows += countComments(t);
                }
            }
        }

    }

    public static long rows(File file) throws FileNotFoundException {
        long rows = 0;
        BufferedReader br = new BufferedReader(new FileReader(file));
        rows = br.lines().count();
        return rows;
    }

    public static long countBlanks(File file) throws IOException {
        BufferedReader input = new BufferedReader(new FileReader(file));
        long blanks = 0;
        String line = null;
        while ((line = input.readLine()) != null) {
            if (line.trim().equals("")) blanks++;
        }
        return blanks;
    }

    public static long countComments(File file) throws IOException {
        BufferedReader input = new BufferedReader(new FileReader(file));
        long comments = 0;
        String line = null;
        while ((line = input.readLine()) != null) {
            line = line.trim();
            if (line.startsWith("//")) { //单行注释
                comments++;
            } else if (line.startsWith("/*")) { //多行及文档注释
                comments++;
                while (!line.endsWith("*/")) {
                    line = input.readLine().trim();
                    comments++;
                }
            } else if (line.contains("/*")) { //行尾多行注释
                line = input.readLine().trim();
                if (line.endsWith("*/")) comments++;
            }

        }
        return comments;
    }

    @Test
    public void test48() {
        String a = "abcdefgh";
        System.out.println(convert(a, 3));
    }

    public String convert(String s, int numRows) {
        //如果行数小于2的话  直接输出s即可
        if (numRows < 2) return s;
        //定义StringBuilder类型的数集合
        List<StringBuilder> rows = new ArrayList<>();
        //集合中的每一行都是stringBuilder类型的
        for (int i = 0; i < numRows; i++) {
            rows.add(new StringBuilder());
        }
        //i=0从第一行开始 flag是控制方向的 当为0的时候就递增  当为numRows-1的时候就递减
        int i = 0, flag = -1;
        //将字符串转换成字符数组
        char[] chars = s.toCharArray();
        //将字符放在对应的每一行上
        for (char c : chars) {
            rows.get(i).append(c);
            if (i == 0 || i == numRows - 1) flag = -flag;
            i += flag;
        }
        //将所有的行 一行行的拼接即可
        StringBuilder stringBuilder = new StringBuilder();
        for (StringBuilder row : rows) {
            stringBuilder.append(row);
        }
        return stringBuilder.toString();
    }


    @Test
    public void test49() {
        int a = -900000;
        System.out.println(reverse(a));
    }

    public int reverse(int x) {
        int res = 0;
        while (x != 0) {
            //每次取末尾数字
            int tmp = x % 10;
            //判断是否大于 最大三十二位整数
            if (res > 214748364 || (res == 214748364 && tmp > 7)) {
                return 0;
            }
            //判断是否小于 最小三十二位整数
            if (res < -214748364 || (res == -214748364 && tmp < -8)) {
                return 0;
            }
            res = res * 10 + tmp;
            x = x / 10;
        }
        return res;
    }

    public boolean isPalindrome(int x) {
        if (x < 0) return false;
        int cur = 0;
        int num = x;
        while (num != 0) {
            cur = cur * 10 + num % 10;
            num = num / 10;
        }
        return cur == x;
    }

    public boolean isEq(int i, int j, String s) {
        boolean b = s.charAt(i--) == s.charAt(j++);
        if (b && i > -1 && j < s.length()) {
            b = isEq(i, j, s);
        }
        return b;
    }

    @Test
    public void test50() {
        System.out.println(isPalindrome(1000021));
    }

    @Test
    public void test51() {
        int[] a = {1, 8, 6, 2, 5, 4, 8, 3, 7};
        System.out.println(maxArea(a));
    }

    public int maxArea(int[] height) {
        int l = 0, r = height.length - 1, ans = 0;
        while (l < r) {
            ans = height[l] < height[r] ?
                    Math.max(ans, (r - l) * height[l++]) :
                    Math.max(ans, (r - l) * height[r--]);
        }
        return ans;
    }

    @Test
    public void test52() {

        System.out.println(intToRoman(43));
    }

    public String intToRoman(int num) {
        // 把阿拉伯数字与罗马数字可能出现的所有情况和对应关系，放在两个数组中，并且按照阿拉伯数字的大小降序排列
        int[] nums = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
        String[] romans = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
        StringBuilder s = new StringBuilder();
        int index = 0;
        //贪心算法
        while (index < nums.length) {
            //同一个罗马数字最多为三个  当为四个的时候会变化
            while (num >= nums[index]) {
                s.append(romans[index]);
                num -= nums[index];
            }
            index++;
        }
        return s.toString();
    }

    @Test
    public void test53() {

        System.out.println(romanToInt("III"));
    }

    public int romanToInt(String s) {
        int sum = 0;
        int preNum = getValue(s.charAt(0));
        //如果preNum小于num 是减法
        for (int i = 1; i < s.length(); i++) {
            char c = s.charAt(i);
            int num = getValue(c);
            if (preNum < num) {
                sum -= preNum;
            } else {
                sum += preNum;
            }
            preNum = num;
        }
        sum += preNum;
        return sum;
    }

    public Integer getValue(char c) {
        switch (c) {
            case 'I':
                return 1;
            case 'V':
                return 5;
            case 'X':
                return 10;
            case 'L':
                return 50;
            case 'C':
                return 100;
            case 'D':
                return 500;
            case 'M':
                return 1000;
            default:
                return 0;
        }
    }

    @Test
    public void test54() {
        String[] strs = {"flower", "abflow", "flight"};
        System.out.println(longestCommonPrefix(strs));
    }

    public String longestCommonPrefix(String[] strs) {

        if (strs.length == 0) return "";
        //获取第一个字符串
        String ans = strs[0];
        //将第一个字符串与后面的字符串作比较
        for (int i = 1; i < strs.length; i++) {
            int j = 0;
            //比较两个字符串的每个字符  直到遇到不一样的字符 停止
            //因为是公共前缀 所以从字符串最左边开始
            for (; j < ans.length() && j < strs[i].length(); j++) {
                if (ans.charAt(j) != strs[i].charAt(j)) break;
            }
            //截取相同的字符串
            ans = ans.substring(0, j);
            //如果新的字符串是空的 直接返回空字符串
            if (ans.equals("")) return ans;
        }
        return ans;
    }

    @Test
    public void test55() {
        int[] nums = {2, 7, 11, 15};
        System.out.println(twoSum(nums, 9));
    }


    public int[] twoSum(int[] nums, int target) {
        //创建一个集合
        Map<Integer, Integer> map = new HashMap<>();
        //将值作为key 下表作为value 放入集合中
        map.put(nums[0], 0);

        for (int i = 1; i < nums.length; i++) {
            if (map.containsKey(target - nums[i])) return new int[]{i, map.get(target - nums[i])};
            map.put(nums[i], i);
        }
        return new int[0];
    }

    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> ans = new ArrayList<>();
        //如果数组为空或其长度小于3 直接输出空数组
        int len = nums.length;
        if (nums == null || len < 3) return ans;
        //先将数组排序 这样最左边的数值将是最小的
        Arrays.sort(nums);
        for (int i = 0; i < len; i++) {
            //如果最小的数值都大于0  那数值之和必定不能为0 结束循环
            if (nums[i] > 0) break;
            //如果一个数值跟它前一个的数值相同 跳过本次循环
            if (i > 0 && nums[i] == nums[i - 1]) continue; // 去重
            //两个指针  指向最小值后面的两端
            int L = i + 1;
            int R = len - 1;
            //如果L小于R 两个指针可以一直变换
            while (L < R) {
                int sum = nums[i] + nums[L] + nums[R];
                //如果sum为0的时候 num[L]与num[L+1]相等 直接跳过 L++
                //如果sum为0的时候 num[R]与num[R-1]相等 直接跳过 R--
                if (sum == 0) {
                    ans.add(Arrays.asList(nums[i], nums[L], nums[R]));
                    while (L < R && nums[L] == nums[L + 1]) L++;//去重
                    while (L < R && nums[R] == nums[R - 1]) R--;//去重
                    //正常的话 等于0的时候 L应当+1 R应当-1
                    L++;
                    R--;
                } else if (sum < 0) {
                    //当sum小于0的时候 L应当+1
                    L++;
                } else if (sum > 0) {
                    //当sum大于0的时候 R应当-1
                    R--;
                }
            }
        }
        return ans;
    }

    public int threeSumClosest(int[] nums, int target) {
        //将数组排序
        Arrays.sort(nums);
        //随便找三个数 计算其和 作为初始三值和
        int min = nums[0] + nums[1] + nums[2];
        int len = nums.length;
        for (int i = 0; i < len; i++) {
            //确定首位置  使用双指针 指向首位置之后和最末的数值
            int L = i + 1;
            int R = len - 1;
            //如果L小于R 两个指针可以一直变换
            while (L < R) {
                //计算三个值的和
                int sum = nums[i] + nums[L] + nums[R];
                //将现在三值的和与target的差值跟原先的三值的和与target的差值比较 将小的作为最接近target的和
                if (Math.abs(sum - target) < Math.abs(min - target)) min = sum;
                if (sum > target) {  //因为已排序  从左到右增加  如果sum值大于目标值 移动大值的指针向左动
                    R--;
                } else if (sum < target) {//如果sum值小于目标值 移动小值的指针向右动
                    L++;
                } else {//如果sum值等于目标值 直接返回即可
                    return min;
                }
            }
        }
        return min;
    }

    @Test
    public void test56() {
        int[] num = {4, 0, 5, -5, 3, 3, 0, -4, -5};
        int target = -2;
        System.out.println(threeSumClosest(num, target));
    }

    @Test
    public void test57() {
        System.out.println(letterCombinations("23"));
    }

    //定义一个数组 将下标与字符串绑定
    String[] str = new String[]{"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    List<String> res = new ArrayList<>();

    public List<String> letterCombinations(String digits) {
        //字符串为空或者长度为0 直接返回空集合
        if (digits == "" || digits.length() == 0) return res;
        //使用回溯(递归)算法 传入动态字符串  题目给的数字字符串  默认从第一个字符开始
        func(new StringBuilder(), digits, 0);
        return res;
    }

    private void func(StringBuilder sb, String digits, int index) {
        //当字母字符串的长度等于题目给的字符串的长度的时候  就是题目要求的结果 将其保存到集合中 并结束本次回溯
        if (sb.length() == digits.length()) {
            res.add(sb.toString());
            return;
        }
        //按顺序获取字符串中的数字  默认从第一个开始  即0
        Integer num = Integer.valueOf(String.valueOf(digits.charAt(index)));
        for (int i = 0; i < str[num].length(); i++) {
            sb.append(str[num].charAt(i));
            func(sb, digits, index + 1);
            //当字母字符串的长度与数字字符串的长度相等的时候 说明已经找到结果了 将最后的字符删除
            //例如 23 首先获取到了ad 当想获取ae的时候  需要ad删除d这个字符
            sb.deleteCharAt(index);
        }
    }


    @Test
    public void test58() {
        int[] nums = new int[]{1, 2, 3, 4};
        System.out.println(fourSum(nums, 10));
    }

    public List<List<Integer>> fourSum(int[] nums, int target) {
        //nums 是数组 n代表几数 start 代表初始位置开始  target代表目标数
        return nNumSum(nums, 4, 0, target);
    }

    private List<List<Integer>> nNumSum(int[] nums, int n, int start, long target) {
        //数组的长度
        int len = nums.length;
        //将数组排序
        Arrays.sort(nums);
        //创建一个集合
        List<List<Integer>> ans = new ArrayList<>();
        if (len < n || n < 2) return ans;
        //两数之和
        if (n == 2) {
            //定义两个指针 一个指向初始位置0 另外一个指向最后一个位置
            int L = start, R = len - 1;
            //如果L < R L可以向又移动 R可以向左移动
            while (L < R) {
                //记录指针对应的元素方便去重
                int low = nums[L], high = nums[R];
                int sum = nums[L] + nums[R];
                if (sum < target) {
                    while (L < R && nums[L] == low) L++;
                } else if (sum > target) {
                    while (L < R && nums[R] == high) R--;
                } else {
                    ans.add(Arrays.asList(nums[L], nums[R]));
                    while (L < R && nums[L] == low) L++;
                    while (L < R && nums[R] == high) R--;
                }
            }
        } else {
            //n > 2
            //for控制重复多少次
            for (int i = start; i < len; i++) {

                long why = (long) target - (long) nums[i];
                if (why > Integer.MAX_VALUE || why < Integer.MIN_VALUE) break;
                List<List<Integer>> sub = nNumSum(nums, n - 1, i + 1, why);
                for (List<Integer> list : sub) {
                    ArrayList<Integer> tmpList = new ArrayList();
                    //加上刚才的数值
                    tmpList.add(nums[i]);
                    //再加上子集合
                    tmpList.addAll(list);
                    ans.add(tmpList);
                }
                //去重
                while (i < len - 1 && nums[i] == nums[i + 1]) i++;
            }
        }
        return ans;
    }

    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        //创建链表 定义预指针
        ListNode pre = new ListNode(0);
        //定义链表当前指针的位置 和预指针的位置相同
        ListNode cur = pre;
        //定义进位数 carry默认为0
        int carry = 0;
        while (l1 != null || l2 != null) {
            //如果l1 不为null 取其值 否则为0
            int x = l1 != null ? l1.val : 0;
            //如果l2 不为null 取其值 否则为0
            int y = l2 != null ? l2.val : 0;
            //计算每一次的总数 等于 两个链表中的数相加并加上进位数
            int sum = x + y + carry;
            //进位数
            carry = sum / 10;
            //实际存储的值
            sum = sum % 10;
            //将sum值存入
            cur.next = new ListNode(sum);
            //改变当前链表指针的位置
            cur = cur.next;
            //如果l1不为空 l1的指针向后移
            if (l1 != null) l1 = l1.next;
            //如果l2不为空 l2的指针向后移
            if (l2 != null) l2 = l2.next;
        }
        //如果 l1、l2 都为null 但是进位数为1
        if (carry == 1) cur.next = new ListNode(carry);
        //当前链表预指针的位置向后一个 就是当前链表的头指针位置
        return pre.next;
    }

    //通过快慢指针可以解决 也就是删除中间元素
    //整体思路是让前面的指针先移动n步，之后前后指针共同移动直到前面的指针到尾部为止
    public ListNode removeNthFromEnd(ListNode head, int n) {
        //定义伪节点，也是预指针 便于返回结果
        ListNode pre = new ListNode(0);
        pre.next = head;
        //定义快慢指针 初始指向预指针
        ListNode fast = pre;
        ListNode slow = pre;
        //快指针先向右移动n个位置
        while (n != 0) {
            fast = fast.next;
            n--;
        }
        //快慢指针一起向右移动 直到快指针指向最后一个位置
        while (fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }
        //当移动结束以后 慢指针指向的位置就是 倒数第n+1个位置
        //要删除倒数第n个位置 只需要让慢指针指向的下一个位置  跳过倒数第n个位置即可
        slow.next = slow.next.next;
        //返回头节点即可 这里返回预指针的下一个 因为 head有可能已经被删除掉
        return pre.next;
    }

    @Test
    public void test59() {
        System.out.println(isValid("(((())))"));
    }

    //有效的括号
    public boolean isValid(String s) {
        if (s.isEmpty() || s.length() % 2 != 0) return false;
        //左括号入栈，遇到右括号时将对应栈顶左括号出栈，则遍历完所有括号后 stack 仍然为空
        Stack<Character> stack = new Stack<>();
        //如果遇到左括号 存对应的右括号 可以不用提前存储对应的括号关系
        for (char c : s.toCharArray()) {
            if (c == '(') {
                stack.push(')');
            } else if (c == '[') {
                stack.push(']');
            } else if (c == '{') {
                stack.push('}');
            } else if (stack.empty() || stack.pop() != c) {
                return false;
            }
        }
        //遍历完 栈中应为空 否则错误
        if (stack.empty()) return true;
        return false;
    }

    //有效的括号
    public boolean isValid2(String s) {
        int length = s.length() / 2;
        for (int i = 0; i < length; i++) {
            s = s.replace("()", "").replace("{}", "").replace("[]", "");
        }
        return s.isEmpty();
    }

    @Test
    public void test60() {
        ListNode l1 = new ListNode(1);
        ListNode l2 = new ListNode(2);
        ListNode[] listNodes = {l1, l2};
//        System.out.println(mergeTwoLists(l1, l2));
        System.out.println(mergeKLists(listNodes));
    }

    //合并两个有序链表
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode pre = new ListNode(0);
        ListNode cur = pre;
        if (list1 == null) return list2;
        if (list2 == null) return list1;
        while (list1 != null || list2 != null) {
            if (list1 == null) {
                cur.next = new ListNode(list2.val);
                list2 = list2.next;
            } else if (list2 == null) {
                cur.next = new ListNode(list1.val);
                list1 = list1.next;
            } else if (list1.val < list2.val) {
                cur.next = new ListNode(list1.val);
                list1 = list1.next;
            } else if (list1.val > list2.val) {
                cur.next = new ListNode(list2.val);
                list2 = list2.next;
            } else {
                cur.next = new ListNode(list1.val);
                cur.next.next = new ListNode(list2.val);
                list1 = list1.next;
                list2 = list2.next;
                cur = cur.next;
            }
            cur = cur.next;
        }
        return pre.next;
    }

    public ListNode mergeKLists(ListNode[] lists) {
        ListNode res = null;
        for (ListNode list : lists) {
            res = mergeTwoLists3(res, list);
        }
        return res;
    }

    public ListNode mergeKLists2(ListNode[] lists) {
        int len = lists.length;
        if (len == 0) return null;
        while (len > 1) {
            int cur = 0;
            for (int i = 0; i < len; i += 2) {
                if (i == len - 1) {
                    lists[cur++] = lists[i];
                } else {
                    lists[cur++] = mergeTwoLists3(lists[i], lists[i + 1]);
                }
            }
            len = cur;
        }
        return lists[0];
    }

    public ListNode mergeKLists3(ListNode[] lists) {
        return merge(lists, 0, lists.length - 1);
    }

    private ListNode merge(ListNode[] lists, int left, int right) {
        if (left == right) {
            return lists[left];
        }
        if (left > right) {
            return null;
        }
        int mid = left + right >> 1;
        ListNode l1 = merge(lists, left, mid);
        ListNode l2 = merge(lists, mid + 1, right);
        return mergeTwoLists3(l1, l2);
    }

    //合并两个有序链表 递归方法
    public ListNode mergeTwoLists2(ListNode list1, ListNode list2) {
        if (list1 == null) {
            return list2;
        } else if (list2 == null) {
            return list1;
        } else if (list1.val < list2.val) {
            list1.next = mergeTwoLists2(list1.next, list2);
            return list1;
        } else {
            list2.next = mergeTwoLists2(list1, list2.next);
            return list2;
        }
    }

    //合并两个有序链表 迭代方法
    public ListNode mergeTwoLists3(ListNode list1, ListNode list2) {
        ListNode pre = new ListNode(0);
        ListNode cur = pre;
        while (list1 != null && list2 != null) {
            if (list1.val < list2.val) {
                cur.next = list1;
                list1 = list1.next;
            } else {
                cur.next = list2;
                list2 = list2.next;
            }
            cur = cur.next;
        }
        cur.next = list1 == null ? list2 : list1;
        return pre.next;
    }

    @Test
    public void test61() {
        System.out.println(generateParenthesis2(2));
    }

    @Test
    public void test62() {
        StringBuilder sb = new StringBuilder();
        sb.append("abcdefg");
        System.out.println(sb.deleteCharAt(0));
    }

    public List<String> generateParenthesis(int n) {
        List<String> res = new ArrayList<>();
        if (n == 0) return res;
        //递归初始值  使用string字符串 因为创建的是新对象可以不用考虑回溯
        dfs("", n, n, res);
        return res;
    }

    private void dfs(String cur, int left, int right, List<String> res) {
        //当左右括号的数量都为0的时候 递归结束 将结果添加到集合中
        if (left == 0 && right == 0) {
            res.add(cur);
            return;
        }
        //如果左边括号的剩余量大于右边括号的剩余量  减枝  结束
        if (left > right) return;
        //如果左括号大于0 将当前结果 加上左括号继续递归 左括号的数量-1
        if (left > 0) {
            dfs(cur + "(", left - 1, right, res);
        }
        //如果右括号大于0 将当前结果 加上右括号继续递归 右括号的数量-1
        if (right > 0) {
            dfs(cur + ")", left, right - 1, res);
        }
    }

    public List<String> generateParenthesis2(int n) {
        List<String> res = new ArrayList<>();
        if (n == 0) return res;
        //递归初始值  使用string字符串 因为创建的是新对象可以不用考虑回溯
        dfs2("", 0, 0, res, n);
        return res;
    }

    private void dfs2(String cur, int left, int right, List<String> res, int n) {
        //当左右括号的数量都为n的时候 递归结束 将结果添加到集合中
        if (left == n && right == n) {
            res.add(cur);
            return;
        }
        //如果左边括号的剩余量大于右边括号的剩余量  减枝  结束
        if (right > left) return;
        //如果左括号小于n 将当前结果 加上左括号继续递归 左括号的数量+1
        if (left < 2) {
            dfs2(cur + "(", left + 1, right, res, n);
        }
        //如果右括号小于n 将当前结果 加上右括号继续递归 右括号的数量+1
        if (right < 2) {
            dfs2(cur + ")", left, right + 1, res, n);
        }
    }

    @Test
    public void test63() {
        ListNode listNode = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4))));
        swapPairs(listNode);
    }

    public ListNode swapPairs(ListNode head) {
        //终止条件  当前无节点 或者只有一个节点的时候终止
        if (head == null || head.next == null) return head;
        //需要交换的两个点为head 和 next
        ListNode next = head.next;
        //next的下一个点指向head
        next.next = head;
        //head的下一个点指向新形成的子链
        head.next = swapPairs(next.next);
        return head;
    }

    public ListNode swapPairs2(ListNode head) {
        ListNode pre = new ListNode(0);
        pre.next = head;
        ListNode temp = pre;
        while (temp.next != null && temp.next.next != null) {
            ListNode start = temp.next;
            ListNode end = temp.next.next;
            temp.next = end;
            start.next = end.next;
            end.next = start;
            temp = start;
        }
        return pre.next;
    }

    public ListNode reverseKGroup(ListNode head, int k) {
        if (head == null || head.next == null) {
            return head;
        }
        //定义一个假节点
        ListNode dummy = new ListNode(0);
        //假节点的next 指向head dummy->1->2->3->4->5
        dummy.next = head;
        //初始化pre和end都指向dummy，pre指的是每次要反转的链表的头节点上的一个节点 end 指的是每次要反转的链表上的一个尾节点
        ListNode pre = dummy;
        ListNode end = dummy;
        while (end.next != null) {
            //循环k次 ，找到需要反转的链表的结尾 这里每次循环都要判断end是否为空 如果为空 end.next 会报空指针
            //dummy->1>2>3>4>5 若k为2 循环2次 end指向2
            for (int i = 0; i < k && end != null; i++) {
                end = end.next;
            }
            //如果end == null，即需要翻转的链表的节点数小于k，不执行翻转
            if (end == null) {
                break;
            }
            //先记录下end.next 方便后面连接链表
            ListNode next = end.next;
            //然后断开链表
            end.next = null;
            //记录下要翻转链表的头节点
            ListNode start = pre.next;
            //翻转链表，pre.next指向翻转后的链表 1->2 变成 2->1 dummy->2->1
            pre.next = reverse(start);
            //翻转后头节点变成最后 通过.next把断开的链表重新连接
            start.next = next;
            //将pre换成下次要翻转的链表的头节点的上一个节点
            pre = start;
            //翻转结束，将end位置换成下次要翻转的链表的头节点的上一个节点
            end = start;
        }
        return head;
    }

    //链表翻转 eg:head: 1->2->3->4
    private ListNode reverse(ListNode head) {
        //单链表为空或只有一个节点，直接返回原单链表
        if (head == null || head.next == null) {
            return head;
        }
        //前一个节点指针
        ListNode preNode = null;
        //当前节点指针
        ListNode curNode = head;
        //下一个节点指针
        ListNode nextCode = null;
        while (curNode != null) {
            nextCode = curNode.next;//nextCode指向下一个节点 保存当前节点后面的链表
            curNode.next = preNode;//当前节点next域指向前一个节点null<-1<-2<-3<-4
            preNode = curNode; //preNode指针向后移动。preNode指向当前节点
            curNode = nextCode;//curNode指针向后移动 下一个节点变成当前节点
        }
        return preNode;
    }

    @Test
    public void test71() {
        ListNode listNode = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4))));
        System.out.println(reverse(listNode));
    }

    public ListNode reverseKGroup2(ListNode head, int k) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode pre = dummy;
        ListNode end = dummy;
        while (end.next != null) {
            for (int i = 0; i < k && end != null; i++) {
                end = end.next;
            }
            if (end == null) {
                break;
            }
            //提前将后续的链表保存
            ListNode next = end.next;
            //断链
            end.next = null;
            ListNode start = pre.next;
            pre.next = reverse2(start);
            start.next = next;
            pre = start;
            end = start;
        }
        return dummy.next;
    }

    //链表翻转 eg:head: 1->2->3->4
    private ListNode reverse2(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode preNode = null;
        ListNode curNode = head;
        ListNode nextNode = null;

        while (curNode != null) {
            nextNode = curNode.next;
            curNode.next = preNode;
            preNode = curNode;
            curNode = nextNode;
        }
        return preNode;
    }

    public int removeDuplicates(int[] nums) {
        //双指针 一个在前i 一个在后j
        //如果两个数相等 后面的指针继续向后移动
        //如果两个数不相等  前指针的下一个位置等于  后指针的数值   并且前指针 后指针都要向后移动
        int i = 0;
        for (int j = 1; j < nums.length; j++) {
            if (nums[i] != nums[j]) {
                nums[++i] = nums[j];
            }
        }
        return i + 1;
    }


    public int removeDuplicates2(int[] nums) {
        if (nums == null || nums.length == 0) return 0;
        int l = 0, r = 1;
        while (r < nums.length) {
            if (nums[l] == nums[r]) {
                r++;
            }else{
                nums[++l] =nums[r++];
            }
        }
        return l+1;
    }


    public int removeElement(int[] nums, int val) {
        if (nums == null || nums.length == 0) return 0;
        int i = 0,j=0;
        while (i<nums.length){
           if(nums[i] != val){
               nums[j++] = nums[i];
           }
           i++;
        }
        return j;
    }

    public int removeElement2(int[] nums, int val) {
        if (nums == null || nums.length == 0) return 0;
        int left = 0;
        for (int right = 0; right < nums.length; right++) {
            if(nums[right] != val){
                nums[left++] = nums[right];
            }
        }
        return left;
    }

    @Test
    public void test73(){
        int[] nums = {1,2,3,4,5};
        System.out.println(removeElement2(nums, 2));
    }

    @Test
    public void test74(){
        HashMap<Integer, String> map = Maps.newHashMap();
        map.put(1,"张三");
        map.put(2,"李四");
        map.put(3,"王五");
        map.put(4,"赵六");
        System.out.println(map.containsKey(1));
        System.out.println(map.containsKey(5));
        System.out.println(map.containsValue("李四"));
        System.out.println(map.containsValue("王二"));

    }

    @Test
    public void test75(){
        System.out.println(Math.ceil(1.5));
        System.out.println(Math.floor(1.5));
        System.out.println(Math.round(1.8));
        System.out.println(Math.round(-1.8));
        System.out.println(Math.round(-1.3));
    }

    @Test
    public void test76(){
        String a = "智运通(北京)科技有限责任公司";
        a = a.replace("(","（").replace(")","）");
        System.out.println(a);
    }

    @Test
    public void test77(){
        List<String> roles = Arrays.asList("1","2","3","4");
        String role = "1";
        Collections.sort(roles);
        System.out.println(roles.contains(role));
        System.out.println(Collections.binarySearch(roles, role));
    }

    @Test
    public void test78(){
        String bankCard = "6236680130003199904";
        System.out.println(bank(bankCard));
    }

    public String bank(String a){
        String str = "";
        if(a.length() > 4){
            str = a.substring(0,4)+" ";
            str += bank(a.substring(4));
        }else {
            str += a;
        }

        return str;
    }

    @Test
    public void test79(){
        String bankCard = "6236680130003199904";
        String split ="(.{4})";
        System.out.println(bankCard.replaceAll(split, "$1 "));
    }

    @Test
    public void test80(){
        StringBuilder sb = new StringBuilder("abcdefg");
        System.out.println(sb.reverse());
    }
    @Test
    public void test81(){
        String a = "asda,asdasd,iuqwoieu";
        String[] split = a.split(",");
        for (int i = 0; i < split.length; i++) {
            System.out.println(split[i]);
        }
    }

    @Test
    public void test82(){
        String a = "a";
        if (a instanceof String) System.out.println("哈哈");
        String b = a.concat("b");
        System.out.println(b);
        System.out.println(b.toUpperCase());
    }
    @Test
    public void test83(){
    int[][] ints = {{1, 2}, {3, 4}, {2, 3}, {1, 3}};
    Arrays.sort(ints,(a,b)->{
        if(a[0] == b [0]) return b[1] - a[1];
        return a[0] - b [0];
    });

        for (int[] anInt : ints) {
            System.out.println(anInt[1]);
        }
    }

    @Test
    public void test84(){
        int[] nums = {1,2,2};
        System.out.println(triangleNumber(nums));
    }

    public int triangleNumber(int[] nums){
        //数组的长度
        int len = nums.length;
        //将数组进行排序  这样做的目的是只需判断前两边之和大于第四边即可
        Arrays.sort(nums);
        //可以组成三角形的数量
        int ans = 0;
        //首先控制第一条边
        for (int i = 0; i < len; i++) {
            //第二三条边从第一条边的下一个位置开始
            int k = i;
            for (int j = i+1; j < len; j++) {
                while (k+1 < len && nums[k+1] < nums[i] + nums[j]){
                    k++;
                }
                ans += Math.max(k-j,0);
            }
        }
        return ans;

    }

    @Test
    public void test85(){
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        list.add(6);
        list.add(7);
        System.out.println(list);
        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
    static final HashMap<Integer,String> MAP = new HashMap<>();


    @Test
    public void test86(){
      Collections.unmodifiableMap(MAP);
      MAP.put(1,"张三");
      MAP.put(1,"李四");
        System.out.println(MAP);
    }

    @Test
    public void test87(){
      String a = "河北省,石家庄市,藁城区";
        String[] split = a.split(",");
        System.out.println(split[0]);
        System.out.println(split[1]);
        System.out.println(split[2]);
    }

    @Test
    public void test88(){
        ArrayList<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list1.add(2);
        list1.add(3);
        list1.add(4);
        System.out.println(list1);
        ArrayList<Integer> list2 = new ArrayList<>();
        list2.add(5);
        list2.add(6);
        list2.add(7);
        list2.add(8);
        System.out.println(list2);
        list1.addAll(list2);
        System.out.println(list1);
    }

    @Test
    public void test89(){
        int [] data = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
        System.out.println(Arrays.toString(data));
        bubbleSort(data);
        System.out.println(Arrays.toString(data));
    }

    private void bubbleSort(int[] data) {
        int len = data.length;
        for (int i = 1; i < len; i++) {//控制轮数
            for (int j = 0; j < len - i; j++) {
                if(data[j] > data[j+1]){
                    int temp = data[j+1];
                    data[j+1] = data[j];
                    data[j] = temp;
                }
            }
        }
    }

}